<?php
/**
 * Log
 *
 * @author   songhuan <iphper@yeah.net>
 * @version   $Id: Log.php 1 2010-08-10 14:40:00Z $
 */
abstract class Log
{
	/**
     * @var array PHP的系统日志属性常量
     */
    protected $_priorities = array(
    	0 => LOG_EMERG,   // 1
   		1 => LOG_ALERT,   // 1
        2 => LOG_CRIT,    // 1
        3 => LOG_ERR,     // 4
        4 => LOG_WARNING, // 5
        5 => LOG_NOTICE,  // 6
        6 => LOG_INFO,    // 6
        7 => LOG_DEBUG    // 6
    );
    
    /**
     * @var array PHP的系统日志属性名
     */
    protected $_priorityNames = array(
        0 => 'EMERG',
        1 => 'ALERT',
        2 => 'CRIT',
        3 => 'ERR',
        4 => 'WARNING',
        5 => 'NOTICE',
        6 => 'INFO',
        7 => 'DEBUG'
    );
    
    /**
     * 处理日志消息，拼接成数组
     *
     * @param  array     $event  log data event
     * @return void
     */
    public function log($message, $priority)
    {
    	if (!array_key_exists($priority, $this->_priorities)) 
    		throw new Exception('Bad log priority');
    	
    	$event = array('dt_create'    => date('Y-m-d H:i:s'),
                       'message'      => $message,
                       'priority'     => $this->_priorities[$priority],
                       'priorityName' => $this->_priorityNames[$priority]);
    	
        $this->_write($event);
    }
    
    /**
     * 如果调用本类方法不存在时，调用的方法
     * 方法名主要是PHP系统日志的属性名
     * 
     * @param string $method  emerg|alert|crit|err|warning|notice|info|debug
     * @param array $params
     */
    public function __call($method, $params)
    {
    	$priority = strtoupper($method);
    	if (($priority = array_search($priority, $this->_priorityNames)) !==  false) 
    		$this->log(array_shift($params), $priority);
    	else 
    		throw new Exception('Bad log priority');
    }
    
    /**
     * 日志消息格式处理
     * 
     * @param array $event
     * @return string 日志消息
     */
    protected function _format($event)
    {
    	$line = "{$event['dt_create']} {$event['priorityName']} ({$event['priority']}): {$event['message']}\n";
		return $line;
    }

    public function shutdown()
    {
    }
    
    public function __destruct()
    {
    	$this->shutdown();
    }

    abstract protected function _write($event);
}